<template>
  <div class="app-container">
    <div class="table-box">
      <!-- 按钮功能区 开始 -->
      <el-row :gutter="10" class="btn-box">
        <el-col
          :xs="24"
          :sm="24"
          :md="24"
          :lg="24"
          :xl="24"
          class="btnfunction-section-col"
        >
          <el-button type="primary" icon="el-icon-plus" :disabled="!checkPermission(['admin.exampleTreeTable.store'])" @click="handleCreate()">{{
            $t('common.create')
          }}</el-button>
          <el-button type="primary" icon="awesome-icon fas fa-sort" :disabled="!checkPermission(['admin.exampleTreeTable.updateSort'])" @click="handleUpdateSort()">
            {{ $t('common.updateSort') }}
          </el-button>
          <el-button-group>
            <el-button
              icon="el-icon-sort"
              :title="$t('common.updown')"
              @click="handleUpDown()"
            >
              {{ $t('common.updown') }}
            </el-button>
          </el-button-group>
          <el-button icon="el-icon-refresh" @click="handleRefresh">{{
            $t('common.refresh')
          }}</el-button>
        </el-col>
      </el-row>
      <!-- 按钮功能区 结束 -->

      <!-- Note that row-key is necessary to get a correct row order.   table当前行高亮属性highlight-current-row-->
      <el-table
        ref="treeTable"
        v-loading="listLoading"
        :data="list"
        row-key="id"
        border
        fit
        highlight-current-row
        :default-expand-all="false"
        style="width: 100%"
        :indent="16"
        :cell-class-name="handleCellClassName"
        :header-cell-class-name="handleHeaderCellClassName"
        @selection-change="handleSelectionChange"
        @select-all="selectAll"
        @select="handleSelectCheckbox"
      >
        <el-table-column type="selection" align="center" fixed="left" />
        <el-table-column
          align="center"
          label="ID"
          type=""
          width="110"
        >
          <template slot-scope="{ row }">
            <span>{{ row.id }}</span>
          </template>
        </el-table-column>

        <el-table-column
          align="left"
          :label="$t('common.name')"
          class-name="menuIcon"
          min-width="150px"
        >
          <template slot-scope="{ row }">
            <span>{{ row.name }}</span>
          </template>
        </el-table-column>

        <el-table-column width="180" :label="$t('common.sort')" align="center">
          <template slot-scope="{ row }">
            <el-input-number v-model="row.sort" controls-position="right" :min="1" />
          </template>
        </el-table-column>

        <el-table-column
          :label="$t('common.status')"
          class-name="status-col"
          width="100"
        >
          <template slot-scope="{ row }">
            <el-switch
              v-model.number="row.status"
              :active-value="1"
              :inactive-value="0"
              :disabled="!checkPermission(['admin.exampleTreeTable.updateStatus'])"
              @change="handleModifyStatus($event,row)"
            />
          </template>
        </el-table-column>

        <el-table-column
          :label="$t('common.created_at')"
          width="200"
          align="center"
        >
          <template slot-scope="{ row }">
            <span>{{ row.created_at }}</span>
          </template>
        </el-table-column>

        <el-table-column
          :label="$t('common.operation')"
          align="center"
          class-name="small-padding fixed-width"
          width="200"
          fixed="right"
        >
          <template slot-scope="{ row, $index }">
            <el-link
              type="primary"
              :underline="false"
              :disabled="!checkPermission(['admin.exampleTreeTable.update']) && !checkPermission(['admin.exampleTreeTable.show'])"
              icon="el-icon-edit"
              :title="$t('common.edit')"
              @click="handleEdit(row)"
            >{{ $t('common.edit') }}
            </el-link>&nbsp;
            <el-link
              type="primary"
              :underline="false"
              :disabled="!checkPermission(['admin.exampleTreeTable.store'])"
              icon="el-icon-plus"
              :title="$t('common.create')"
              @click="handleCreate(row)"
            >{{ $t('common.create') }}
            </el-link>&nbsp;
            <el-link
              type="primary"
              :underline="false"
              :disabled="!checkPermission(['admin.exampleTreeTable.destroy'])"
              icon="el-icon-delete"
              :title="$t('common.delete')"
              @click="handleDelete(row, $index)"
            >{{ $t('common.delete') }}
            </el-link>&nbsp;
          </template>
        </el-table-column>
      </el-table>
    </div>

    <el-dialog
      :title="editType?$t('common.edit'):$t('common.create')"
      :visible.sync="treeTableEditDialogFormVisible"
      custom-class="jsp-dialog-modal-box"
      :close-on-click-modal="false"
      destroy-on-close
    >
      <tree-table-edit-dialog v-if="treeTableEditDialogFormVisible" ref="treeTableEditDialog" :edit-detail="editDetail" @error="handleEditError" @success="handleEditSuccess" />
      <div slot="footer" class="dialog-footer">
        <el-button @click="treeTableEditDialogFormVisible = false">{{ $t('common.cancel') }}</el-button>
        <el-button
          type="primary"
          :loading="editDetailSubmitLoading"
          :disabled="editType&&!checkPermission(['admin.exampleTreeTable.update']) || !editType&&!checkPermission(['admin.exampleTreeTable.store'])"
          @click="handleTreeTableEditSubmit"
        >{{ $t('common.submit') }}</el-button>
      </div>
    </el-dialog>

  </div>
</template>

<script>
import { index, updateStatus, destory, updateSort } from '@/api/example/tree-table'
// import { flatToTree } from '@/utils/tree'
import TreeTableEditDialog from './editDialog'
import checkPermission from '@/utils/permission'

export default {
  name: 'TreeTableIndex',
  components: {
    TreeTableEditDialog
  },
  data() {
    return {
      tableKey: 0,
      list: [], // 扁平数据结构
      listQuery: {
        sort: '+sort'
      },
      total: 0,
      listLoading: true,
      multipleSelection: [],
      isbuildCheckboxRelation: true, // 行级复选框选择时是否关联上下级,
      treeTableEditDialogFormVisible: false,
      editType: 0,
      editDetail: {},
      editDetailSubmitLoading: false
    }
  },
  created() {
    this.getList()
  },
  methods: {
    checkPermission,
    async getList() {
      this.listLoading = true
      await index(this.listQuery).then((response) => {
        const { items, total } = response.data
        this.total = total
        items.forEach((item) => {
          item.isSelected = false
        })
        this.list = items
        this.listLoading = false
      }).catch(() => {
        this.closeBack()
      })
    },
    handleDelete(row, index) {
      this.$confirm(this.$t('common.delete_confirm_tips'), {
        confirmButtonText: this.$t('common.confirm'),
        cancelButtonText: this.$t('common.cancel'),
        type: 'warning'
      })
        .then(() => {
          destory(row.id).then((response) => {
            this.$message.success(response.message)
            this.getList()
          }).catch(() => {
          })
        })
        .catch(() => {
          this.$message.info(this.$t('common.canceled'))
        })
    },
    handleUpdateSort() {
      if (this.multipleSelection.length === 0) {
        this.$message.warning(this.$t('common.please_choose_sort_tips'))
        return
      }
      const params = this.multipleSelection.map((row, index) => {
        return { id: row.id, sort: row.sort }
      })
      updateSort({ sort: params }).then((response) => {
        this.$message.success(response.message)
        this.getList()
      }).catch(() => {
      })
    },
    handleModifyStatus($event, row) {
      updateStatus(row.id, { status: $event }).then((response) => {
        this.$message.success(response.message)
        row.status = $event
      }).catch(() => {
      })
    },
    downUpData(data, isExpand) {
      data.forEach((i) => {
        if (i.children) {
          this.$refs.treeTable.toggleRowExpansion(i, isExpand)
          this.downUpData(i.children, isExpand)
        }
      })
    },
    handleUpDown() {
      this.isExpand = !this.isExpand
      this.downUpData(this.list, this.isExpand)
    },
    handleRefresh() {
      this.getList()
    },
    handleSelectionChange(val) {
      this.multipleSelection = val
    },
    // 获取所有子选项复选框总数量、已选中数量
    getAllChildrenCheckboxTotal(children_data) {
      const result = { total: 0, selected: 0 }
      if (!children_data) return result
      children_data.forEach(item => {
        result.total++
        result.selected += item.isSelected ? 1 : 0
        if (item.children) {
          const getC = this.getAllChildrenCheckboxTotal(item.children)
          result.total += getC.total
          result.selected += getC.selected
        }
      })
      return result
    },
    // 表级全选/取消复选框
    selectAll(selection) {
      this.list.forEach((item) => {
        this.executeSelectRow(selection, item)
      })
    },
    // 执行行级选择/取消
    executeSelectRow(selection, row) {
      // 状态：选中、未选中
      // 样式：is-checked:选中；未选中：空字符串；不确定状态：jsp-is-indeterminate

      // 选中状态判断
      const rowIsSelected = selection.some(item => { return row.id === item.id })
      row.isSelected = rowIsSelected
      const that = this

      // 设置所有子项选中/取消
      function setChildrensCheckboxSelected(children_data) {
        children_data.forEach(item => {
          that.$nextTick(() => {
            item.isSelected = rowIsSelected
            that.$refs.treeTable.toggleRowSelection(item, rowIsSelected)
            if (item.children) {
              setChildrensCheckboxSelected(item.children, rowIsSelected)
            }
          })
        })
      }

      // 设置所有父级选中状态
      function setAllParentSelectedStatus(data) {
        if (data.length === 0) return
        for (let i = 0; i < data.length; i++) {
          if (data[i].id === row.id) {
            return []
          } else {
            if (data[i].children) {
              const res = setAllParentSelectedStatus(data[i].children)
              if (res !== undefined) {
                that.$nextTick(() => {
                  if (rowIsSelected) { // 选中情况
                    data[i].isSelected = true
                  } else { // 取消选中情况
                    const getCT = that.getAllChildrenCheckboxTotal(data[i].children)
                    const isSelected = getCT.selected > 0
                    data[i].isSelected = isSelected
                  }
                  that.$refs.treeTable.toggleRowSelection(data[i], data[i].isSelected)
                })
                return []
              }
            }
          }
        }
      }

      // 子级选中状态处理
      if (row.children) {
        // 设置子选项选中状态
        setChildrensCheckboxSelected(row.children)
      }
      // 设置父选项选中状态
      setAllParentSelectedStatus(this.list)
    },
    // 行级复选框选中/取消事件
    handleSelectCheckbox(selection, row) {
      this.isbuildCheckboxRelation && this.executeSelectRow(selection, row)
    },
    // 设置列样式名
    handleCellClassName(cell) {
      if (this.isbuildCheckboxRelation && cell.columnIndex === 0) {
        const getCT = this.getAllChildrenCheckboxTotal(cell.row.children)
        if (getCT.selected > 0 && getCT.selected < getCT.total) {
          return 'jsp-is-indeterminate'
        }
        return ''
      }
    },
    // 设置头部列样式
    handleHeaderCellClassName(cell) {
      if (this.isbuildCheckboxRelation && cell.columnIndex === 0) {
        let total = 0
        let selected_total = 0
        this.list.forEach((item) => {
          if (item.children) {
            const getCT = this.getAllChildrenCheckboxTotal(item.children)
            total += getCT.total
            selected_total += getCT.selected
          }
        })
        if (selected_total > 0 && selected_total < total) {
          return 'jsp-is-indeterminate'
        }
        return ''
      }
    },
    handleCreate(parent) {
      this.editDetail.id = 0
      this.editDetail.parent_id = parent !== undefined ? parent.id : 0
      this.treeTableEditDialogFormVisible = true
      this.editType = 0
    },
    handleEdit(row) {
      this.editDetail = { id: row.id, parent_id: row.parent_id }
      this.treeTableEditDialogFormVisible = true
      this.editType = 1
    },
    // 提交编辑表单
    // eslint-disable-next-line handle-callback-err
    handleTreeTableEditSubmit() {
      this.editDetailSubmitLoading = true
      this.$refs.treeTableEditDialog.onSubmit()
    },
    // eslint-disable-next-line handle-callback-err
    handleEditError(error) {
      this.editDetailSubmitLoading = false
      // error !== null && this.$message.error(error)
    },
    handleEditSuccess(response) {
      this.editDetailSubmitLoading = false
      this.$message.success(response.message)
      this.treeTableEditDialogFormVisible = false
      this.handleRefresh()
    }
  }
}
</script>

<style scoped type="scss">
</style>

